var testScreenIdx = 0;
var elapseMls = 0;
var frameCount = 0;
var renderFPS = null;
window.colorPicker = {};

var currentTool = null;
var currentPickColor = null;
var shadowMap = null;
//--TOOL------------------------------------------------------
// Transform toolquadTree
const NODE_TOOL_MOVE      = 1;
const NODE_TOOL_SCALE     = 2;
const NODE_TOOL_ROTATE    = 3;
const NODE_TOOL_SELECT    = 4;

// Paint tool
const GRASS_POINT_PAINT = 11;
const GRASS_BOX_PAINT = 12;
const NODE_POINT_PAINT = 13;

const PICK_COLOR_RED      = 1;
const PICK_COLOR_GREEN    = 2;
const PICK_COLOR_BLUE     = 3;
const PICK_COLOR_WHITE    = 4;
///////////////////////////////////////////////////////////////////
// Node function
function removeNodeFromMaterial()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  if (ui_node && ui_node.sceneNode) {
    var sceneNode = ui_node.sceneNode;
    var mName = getTextFromList("CommonNodeTab_NodeMaterialList");
    var m = getMaterialFromName(mName);
    sceneNode.removeMaterial(m);
    displayActiveNode(ui_node,1);
  }  
}
function removeNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  if (ui_node && ui_node.sceneNode) {
    var sceneNode = ui_node.sceneNode;
    if (confirm("Are you sure want to delete '" + sceneNode.name + "' node?")) {
      sceneNode.destructor();
      updateNodeTree("Node_tab_NodeTree");
    }
  }
}
function updateGrassNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  var sceneNode = ui_node.sceneNode;
  sceneNode.type0Percent= parseFloat( getTextFromInput("GrassNodeTab_Type0Percent"));
  sceneNode.type1Percent= parseFloat( getTextFromInput("GrassNodeTab_Type1Percent"));   
  sceneNode.type2Percent= parseFloat( getTextFromInput("GrassNodeTab_Type2Percent")); 
  sceneNode.type3Percent= parseFloat( getTextFromInput("GrassNodeTab_Type3Percent")); 
  sceneNode.clumpHeightRange.x = parseFloat( getTextFromInput("GrassNodeTab_HeightRangeMin"));  
  sceneNode.clumpHeightRange.y = parseFloat( getTextFromInput("GrassNodeTab_HeightRangeMax")); 
  sceneNode.clumpRatioRange.x =  parseFloat( getTextFromInput("GrassNodeTab_RatioRangeMin")); 
  sceneNode.clumpRatioRange.y =  parseFloat( getTextFromInput("GrassNodeTab_RatioRangeMax")); 
}
function updateMeshNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  var sceneNode = ui_node.sceneNode;
  sceneNode.setMesh(this.game.resourceManager.getMesh( getTextFromList("MeshNodeTab_Mesh")));
  sceneNode.shouldCreatePhysicsBody = document.getElementById("MeshNodeTab_physicsbody").checked;
}
function updateNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  var sceneNode = ui_node.sceneNode;
  
  var name =  document.getElementById("CommonNodeTab_Name").value;
  if (name != sceneNode.name) {
    var isExist = tree.getNodeByKey(name);
    if (isExist) {
      alert("This node name is already used! Plz choice another");
      return;
    }
    else
    {
      sceneNode.name = name;
      updateNodeTree("Node_tab_NodeTree",name);
    }
  }
  sceneNode.setVisible(document.getElementById("CommonNodeTab_Visible").checked);
  
  var x = parseFloat(document.getElementById("CommonNodeTab_PositionX").value);
  var y = parseFloat(document.getElementById("CommonNodeTab_PositionY").value);
  var z = parseFloat(document.getElementById("CommonNodeTab_PositionZ").value);
  sceneNode.setPositionXYZ(x,y,z);
  x = parseFloat(document.getElementById("CommonNodeTab_ScaleX").value);
  y = parseFloat(document.getElementById("CommonNodeTab_ScaleY").value);
  z = parseFloat(document.getElementById("CommonNodeTab_ScaleZ").value);
  sceneNode.setScaleXYZ(x,y,z);
  x = parseFloat(document.getElementById("CommonNodeTab_RotateX").value);
  y = parseFloat(document.getElementById("CommonNodeTab_RotateY").value);
  z = parseFloat(document.getElementById("CommonNodeTab_RotateZ").value);
  var angle = parseFloat(document.getElementById("CommonNodeTab_RotateAngle").value);
  sceneNode.setRotateXYZ(x,y,z,angle);
}
function addNodeToMaterial()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  var sceneNode = ui_node.sceneNode;
  var mName = getTextFromList("CommonNodeTab_MaterialList");
  if(sceneNode.materials[mName])
    return;
  var material = getMaterialFromName(mName);
  sceneNode.addMaterial(material);
  displayActiveNode(ui_node,1);
}
function displayActiveNode(dtnode,activeTabId)
{
  clearInfoTab();
  var sceneNode = dtnode.sceneNode;
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  screen.selectedNode = sceneNode;
  addInfoTab("infoTabs/CommonNodeTab.html","Common");  
  // Update info for common tab
  var ele = document.getElementById("CommonNodeTab_Class");
  document.getElementById("CommonNodeTab_Visible").checked = sceneNode.isVisible;
  document.getElementById("CommonNodeTab_Class").value = getClassName(sceneNode); 
  document.getElementById("CommonNodeTab_Name").value = sceneNode.name;
  document.getElementById("CommonNodeTab_PositionX").value = sceneNode.position.x.toFixed(2) +"";
  document.getElementById("CommonNodeTab_PositionY").value = sceneNode.position.y.toFixed(2)+"";
  document.getElementById("CommonNodeTab_PositionZ").value = sceneNode.position.z.toFixed(2)+"";
  
  document.getElementById("CommonNodeTab_ScaleX").value = sceneNode.scale.x.toFixed(2)+"";
  document.getElementById("CommonNodeTab_ScaleY").value = sceneNode.scale.y.toFixed(2)+"";
  document.getElementById("CommonNodeTab_ScaleZ").value = sceneNode.scale.z.toFixed(2)+"";
  
  document.getElementById("CommonNodeTab_RotateX").value = sceneNode.rotate.x.toFixed(2)+"";
  document.getElementById("CommonNodeTab_RotateY").value = sceneNode.rotate.y.toFixed(2)+"";
  document.getElementById("CommonNodeTab_RotateZ").value = sceneNode.rotate.z.toFixed(2)+"";
  
  document.getElementById("CommonNodeTab_RotateAngle").value = sceneNode.angle.toFixed(2)+"";
  
  document.getElementById("CommonNodeTab_NodeMaterialList").options.length = 0;
  for(var i in sceneNode.materials)
  {    
    addOptionToList(i,"CommonNodeTab_NodeMaterialList");  
  }  
  var eList = this.game.getScreen(DESIGN_SCREEN_ID).scene3d.effects;
  var eLen = eList.length;
  document.getElementById("CommonNodeTab_MaterialList").options.length = 0; 
  for(var i=0;i<eLen;i++)
  {
    var mList = eList[i].materialList; 
    for(var m in mList  )
    {
      addOptionToList(m,"CommonNodeTab_MaterialList");  
    }
  }
  document.getElementById("CommonNodeTab_Name").value = sceneNode.name;
  //Update special info tab  
  var nodeClass = getClassName(sceneNode);
  if(nodeClass=="gewMeshNode")
  {
    addInfoTab("infoTabs/MeshNodeTab.html","Mesh");
    if(sceneNode.mesh)
      updateMeshListInto("MeshNodeTab_Mesh", getMeshName(sceneNode.mesh) );
    else
      updateMeshListInto("MeshNodeTab_Mesh");
    if(sceneNode.shouldCreatePhysicsBody)
    {
      document.getElementById("MeshNodeTab_physicsbody").checked = sceneNode.shouldCreatePhysicsBody;
    }
  }
  else if(nodeClass=="gewGrassNode")
  {
    addInfoTab("infoTabs/GrassNodeTab.html","Grass");
    document.getElementById("GrassNodeTab_Type0Percent").value = sceneNode.type0Percent;
    document.getElementById("GrassNodeTab_Type1Percent").value = sceneNode.type1Percent;
    document.getElementById("GrassNodeTab_Type2Percent").value = sceneNode.type2Percent;
    document.getElementById("GrassNodeTab_Type3Percent").value = sceneNode.type3Percent;
    document.getElementById("GrassNodeTab_HeightRangeMin").value = sceneNode.clumpHeightRange.x;
    document.getElementById("GrassNodeTab_HeightRangeMax").value = sceneNode.clumpHeightRange.y;
    document.getElementById("GrassNodeTab_RatioRangeMin").value = sceneNode.clumpRatioRange.x;
    document.getElementById("GrassNodeTab_RatioRangeMax").value = sceneNode.clumpRatioRange.y;
    document.getElementById("GrassNodeTab_ClumpCount").value = sceneNode.clumpNum;
  }
  else if(nodeClass=="gewWaterNode")
  {
    addInfoTab("infoTabs/MeshNodeTab.html","Mesh");
    if(sceneNode.mesh)
      updateMeshListInto("MeshNodeTab_Mesh",getMeshName(sceneNode.mesh));
    else
      updateMeshListInto("MeshNodeTab_Mesh");
  }
  
  if(activeTabId)
  {
    setActiveInfoTab(activeTabId);
  }
  else
  {
    setActiveInfoTab(1);
  }
}
function openAddNodeDiaglog()
{
  var typeName = getTextFromList("Node_tab_NodeTypeList");
  if(typeName=="TerrainNode")
    $("#addTerrainNodeDialog").dialog("open");
  else
    $("#addNodeDialog").dialog("open");
}
function paintNode(sceneNode,point,normal)
{
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var copy = sceneNode.dup(); 
  
  // Find unique name
  var name = sceneNode.name;
  var new_name;
  var sub = 0;
  while(true)
  {
    new_name = name+"_"+sub;
    var isExist = screen.scene3d.getNodeByName(new_name);
    if(!isExist)
      break;
    sub++;
  }
  copy.name = new_name;
  var parentMat = sceneNode.parent.modelMat;
  if(!parentMat)
    var parentPos = new gewVec3();
  else
    var parentPos = new gewVec3(parentMat.data[12],parentMat.data[13],parentMat.data[14]);
  copy.setPosition(point.sub(parentPos));
  
  var minScale = parseFloat(getTextFromInput("PaintToolTab_MinScale"));
  var maxScale = parseFloat(getTextFromInput("PaintToolTab_MaxScale"));
  var scaleFactor = gewMix(minScale,maxScale, Math.random());
  var scale = sceneNode.getScale();
  copy.setScale(scale.mulScalar(scaleFactor));
  
  if (document.getElementById("PaintToolTab_RotateByNormal").checked == true) {
    var xz = new gewVec3(0, 1, 0);
    var rotateAxis = xz.cross(normal);
    var angle = xz.angleFrom(normal);
    
    var maxErrorAngle = parseFloat(getTextFromInput("PaintToolTab_ErrorAngle"));
    var errorAngle = gewMix(0, maxErrorAngle, Math.random());
    var tanError = Math.tan(errorAngle * GEW_MATH_DEGREE_TO_RADIAN);
    var randomXZVec = new gewVec3(Math.random() - 0.5, 0, Math.random() - 0.5);
    
    var mat = gewMat4.getRotate(rotateAxis, angle);
    mat.mulVec3NoTranslate(randomXZVec, randomXZVec);
    randomXZVec.normalize();
    randomXZVec.mulScalar(gewMix(0, tanError, Math.random()), randomXZVec);
    var new_normal = normal.add(randomXZVec);
    new_normal.normalize();
    var new_rotateAxis = xz.cross(new_normal);
    var new_angle = xz.angleFrom(new_normal);
    
    var rMat1 = gewMat4.getRotate(new_rotateAxis, new_angle);
    var rMat2 = gewMat4.getRotate(new gewVec3(0, 1, 0), gewMix(0, 2 * Math.PI, Math.random()));
    var rMat3 = rMat1.mul(rMat2);
    
    var combineAxis = new gewVec3();
    var combineAngle = rMat3.extractRotateAxis(combineAxis);
    combineAngle *= GEW_MATH_RADIAN_TO_DEGREE;
    copy.setRotate(combineAxis, combineAngle);
  }
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var parentName = sceneNode.parent.name;
  if(parentName=="root")
    var ui_parent = tree.getRoot();
  else
    var ui_parent = tree.getNodeByKey(sceneNode.parent.name);
  var icon_file = false;
  ui_parent.addChild({title:copy.name, key:copy.name,icon:icon_file});
  var ui_child = tree.getNodeByKey(copy.name);
  ui_child.sceneNode = copy;
}
function dupNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  var sceneNode = ui_node.sceneNode;
  var copy = sceneNode.dup();  
  // Find unique name
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var name = sceneNode.name;
  var new_name;
  var sub = 0;
  while(true)
  {
    new_name = name+"_"+sub;
    var isExist = screen.scene3d.getNodeByName(new_name);
    if(!isExist)
      break;
    sub++;
  }
  copy.name = new_name;
  updateNodeTree("Node_tab_NodeTree",sceneNode.name );
}
function addTerrainNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  if(!ui_node)
    ui_node = tree.getRoot();
  var parent = ui_node.sceneNode;
  var mName = getTextFromInput("addTerrainNodeDialog_Name"); 
  var isExist = tree.getNodeByKey(mName);
  if(isExist)
  {
    alert("This node name is already used! Plz choice another");
    return;
  }
  var clipmapSize = parseInt( getTextFromInput("addTerrainNodeDialog_ClipmapSize") );
  var gridSpace   = parseInt( getTextFromInput("addTerrainNodeDialog_GridSpace") );
  var levelCount  = parseInt( getTextFromInput("addTerrainNodeDialog_LevelCount") );
  
  var node = new gewTerrainNode(this.game.gl,clipmapSize,gridSpace,levelCount,mName);
  parent.appendChild(node);
  $("#addTerrainNodeDialog").dialog("close");  
  updateNodeTree("Node_tab_NodeTree",mName);
}
function addNode()
{
  var tree = $("#Node_tab_NodeTree").dynatree("getTree");
  var ui_node = tree.getActiveNode();
  if(!ui_node)
    ui_node = tree.getRoot();
  var parent = ui_node.sceneNode;
  var typeName = getTextFromList("Node_tab_NodeTypeList");
  var nodeClassName = "gew"+ typeName;
  var mName = getTextFromInput("addNodeDialog_Name"); 
  
  var isExist = tree.getNodeByKey(mName);
  if(isExist)
  {
    alert("This node name is already used! Plz choice another");
    return;
  }
  
  if(typeName=="GrassNode")
  {
    var node = new gewGrassNode(this.game.gl,mName);
  }
  else
  {
    eval("var node = new "+nodeClassName+"(\""+mName+"\")" );
  }
  parent.appendChild(node);
  $("#addNodeDialog").dialog("close");
  
  updateNodeTree("Node_tab_NodeTree",mName);
}
function updateNodeTree(tree_id,activeNodeName)
{
  eval('var tree = $("#'+tree_id+'").dynatree("getTree");')
  var root  =tree.getRoot();
  root.removeChildren();
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  root.sceneNode = screen.scene3d.root;
  updateSubTree(root,screen.scene3d.root,tree); 
  tree.activateKey(activeNodeName);   
}
function updateSubTree(ui_subroot,scene_subroot,tree)
{
  var children = scene_subroot.children;
  var len = children.length;
  for(var i =0;i<len;i++)
  {
    var child = children[i];
    var icon_file = false;
    ui_subroot.addChild({title:child.name, key:child.name,icon:icon_file});
    var ui_child = tree.getNodeByKey(child.name);
    ui_child.sceneNode = child;
    updateSubTree(ui_child,child,tree);
  }
}
///////////////////////////////////////////////////////////////////
// Material functions
function removeMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  if (confirm("Are you sure want to delete '" + mName + "' material?")) {
    var m = e.materialList[mName];
    m.destructor();
    updateMaterialList("Scene_Material_EffectList", "Scene_Material_MaterialList");
  }
}
function displayMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  
  var className = getClassName(m);
  
  clearInfoTab();
  addInfoTab("infoTabs/CommonMaterialTab.html","Common");
  document.getElementById("CommonMaterialTab_BatchModeList").selectedIndex = m.batchType;
  if(!m)
    return;
  switch(className)
  {
    case "gewCSMMaterial":
      //Create ui
      addInfoTab("infoTabs/CSMMaterialTab.html","Shadow map");
      $("#CSMMaterialTab_AlphaRef").slider( {
         slide: function(event, ui)
         {
           updateCSMMaterial();
         }       
         } );
      document.getElementById("CSMMaterialTab_Type").selectedIndex = m.type;
      updateTextureListInto("CSMMaterialTab_Texture", getTexName(m.texture));
      $("#CSMMaterialTab_AlphaRef").slider("value", m.alphaRef*100. ); 
      break;      
    case "gewPhongMaterial":
      //Create ui
      addInfoTab("infoTabs/PhongMaterialTab.html","Phong");
      createColorPicker("colorSelector01","updatePhongMaterial");
      createColorPicker("colorSelector02","updatePhongMaterial");
      createColorPicker("colorSelector03","updatePhongMaterial");
      
      $("#PhongMaterialTab_AlphaRef").slider( {
         slide: function(event, ui)
         {
           updatePhongMaterial();
         }       
         } );
      //Update info into ui
      updateTextureListInto("PhongMaterialTab_Texture", getTexName(m.texture));
      setColorPicker("colorSelector01",m.ambient.x,m.ambient.y,m.ambient.z)
      setColorPicker("colorSelector02",m.diffuse.x,m.diffuse.y,m.diffuse.z)
      setColorPicker("colorSelector03",m.specular.x,m.specular.y,m.specular.z)
      document.getElementById("PhongMaterialTab_Shininess").value = m.shininess;   
      document.getElementById("PhongMaterialTab_FaceCulling").checked = m.faceCulling;
      $("#PhongMaterialTab_AlphaRef").slider("value", m.alphaRef*100. ); 
      break;
    case "gewGrassMaterial":
      // Create ui
      addInfoTab("infoTabs/GrassMaterialTab.html","Grass");
      $("#GrassMaterialTab_SwingFactor").slider( {
         slide: function(event, ui)
         {
           updateGrassMaterial();
         }       
         } );
      $("#GrassMaterialTab_AlphaRef").slider( {
         slide: function(event, ui)
         {
           updateGrassMaterial();
         }       
         } );
      // Update info into ui
      updateTextureListInto("GrassMaterialTab_Texture", getTexName(m.grassPackTexture));
      document.getElementById("GrassMaterialTab_Strength").value = m.strength;
      $("#GrassMaterialTab_SwingFactor").slider("value", m.swingFactor*100. );
      $("#GrassMaterialTab_AlphaRef").slider("value", m.alphaRef*100. );   
      break;
    case "gewTerrainMaterial":
      // Create ui
      addInfoTab("infoTabs/TerrainMaterialTab.html","Terrain");
      // update info into ui
      updateFloatmapList("TerrainMaterialTab_Heightmap", getFloatMapName(m.heightMap));
      updateTextureListInto("TerrainMaterialTab_Texturemap", getTexName(m.textureMap));
      updateTextureListInto("TerrainMaterialTab_Materialmap", getTexName(m.alphaMap));
      updateTextureListInto("TerrainMaterialTab_MaterialTex0", getTexName(m.materialTex0));      
      updateTextureListInto("TerrainMaterialTab_MaterialTex1", getTexName(m.materialTex1));
      updateTextureListInto("TerrainMaterialTab_MaterialTex2", getTexName(m.materialTex2));
      updateTextureListInto("TerrainMaterialTab_MaterialTex3", getTexName(m.materialTex3));
      
      document.getElementById("TerrainMaterialTab_TerrainSize").value = m.terrainSize;
      document.getElementById("TerrainMaterialTab_UpdateStep").value = m.updateStep;
      document.getElementById("TerrainMaterialTab_MaterialSize").value = m.materialSize;
      document.getElementById("TerrainMaterialTab_MaterialBlendRadius").value = m.materialBlendRadius;
      document.getElementById("TerrainMaterialTab_MaterialBlendFactor0").value = m.materialBlendFactor[0];
      document.getElementById("TerrainMaterialTab_MaterialBlendFactor1").value = m.materialBlendFactor[1];
      document.getElementById("TerrainMaterialTab_MaterialBlendFactor2").value = m.materialBlendFactor[2];
      document.getElementById("TerrainMaterialTab_MaterialBlendFactor3").value = m.materialBlendFactor[3];
      
      document.getElementById("TerrainMaterialTab_Ambient0").value = m.ambient.x;
      document.getElementById("TerrainMaterialTab_Ambient1").value = m.ambient.y;
      document.getElementById("TerrainMaterialTab_Ambient2").value = m.ambient.z;
      document.getElementById("TerrainMaterialTab_Diffuse0").value = m.diffuse.x;
      document.getElementById("TerrainMaterialTab_Diffuse1").value = m.diffuse.y;
      document.getElementById("TerrainMaterialTab_Diffuse2").value = m.diffuse.z;
      break;
    case "gewWaterMaterial":
      // Create ui
      addInfoTab("infoTabs/WaterMaterialTab.html","Water");
      // update info into ui
      updateTextureListInto("WaterMaterialTab_NormalMap", getTexName(m.normalMap));
      updateTextureListInto("WaterMaterialTab_ReflectionMap", getTexName(m.reflectionMap));
      document.getElementById("WaterMaterialTab_WaveSize").value = m.waveSize;
      document.getElementById("WaterMaterialTab_Strength").value = m.strength;
      
      document.getElementById("WaterMaterialTab_ColorR").value = m.waterColor[0];
      document.getElementById("WaterMaterialTab_ColorG").value = m.waterColor[1];
      document.getElementById("WaterMaterialTab_ColorB").value = m.waterColor[2];
      document.getElementById("WaterMaterialTab_ColorA").value = m.waterColor[3];
      break;
    default:
      break;
  }  
}
function updateMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  if(!m)
    return;
  m.batchType = document.getElementById("CommonMaterialTab_BatchModeList").selectedIndex;
}
function updateCSMMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  if(!m)
    return;
  m.type = document.getElementById("CSMMaterialTab_Type").selectedIndex;
  m.texture = this.game.resourceManager.getTexture( getTextFromList("CSMMaterialTab_Texture") );
  m.alphaRef = $("#CSMMaterialTab_AlphaRef").slider("value")/100.;    
}
function updateWaterMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  if(!m)
    return;
  
  m.normalMap = this.game.resourceManager.getTexture( getTextFromList("WaterMaterialTab_NormalMap") );
  m.reflectionMap = this.game.resourceManager.getTexture( getTextFromList("WaterMaterialTab_ReflectionMap") );
  
  m.waveSize =  parseFloat( getTextFromInput("WaterMaterialTab_WaveSize") );
  m.strength =  parseFloat( getTextFromInput("WaterMaterialTab_Strength") );
  
  m.waterColor[0] =  parseFloat( getTextFromInput("WaterMaterialTab_ColorR") );
  m.waterColor[1] =  parseFloat( getTextFromInput("WaterMaterialTab_ColorG") );
  m.waterColor[2] =  parseFloat( getTextFromInput("WaterMaterialTab_ColorB") );
  m.waterColor[3] =  parseFloat( getTextFromInput("WaterMaterialTab_ColorA") );
}
function updateGrassMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  if(!m)
    return;
  
  m.grassPackTexture = this.game.resourceManager.getTexture( getTextFromList("GrassMaterialTab_Texture") );
  m.strength =  document.getElementById("GrassMaterialTab_Strength").value;
  m.swingFactor =  $("#GrassMaterialTab_SwingFactor").slider("value")/100.;
  m.alphaRef = $("#GrassMaterialTab_AlphaRef").slider("value")/100.;   
}
function updatePhongMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  m.texture = this.game.resourceManager.getTexture( getTextFromList("PhongMaterialTab_Texture"));
    
  var ambient = window.colorPicker["colorSelector01"];
  var diffuse = window.colorPicker["colorSelector02"];
  var specular = window.colorPicker["colorSelector03"];
  m.ambient.set(ambient.r/255.,ambient.g/255.,ambient.b/255. );
  m.diffuse.set(diffuse.r/255.,diffuse.g/255.,diffuse.b/255. );
  m.specular.set(specular.r/255.,specular.g/255.,specular.b/255. );
  m.shininess = parseFloat(getTextFromInput("PhongMaterialTab_Shininess"));
  m.alphaRef = $("#PhongMaterialTab_AlphaRef").slider("value")/100.;
  m.faceCulling = faceCulling = document.getElementById("PhongMaterialTab_FaceCulling").checked;
}
function updateTerrainMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  if(!e)
    return;
  var mName = getTextFromList("Scene_Material_MaterialList");
  var m = e.materialList[mName];
  var rman = this.game.resourceManager;
  m.heightMap = rman.getFloatMap( getTextFromList("TerrainMaterialTab_Heightmap") );
  screen.scene3d.heightMap = m.heightMap;
  m.textureMap = rman.getTexture(getTextFromList("TerrainMaterialTab_Texturemap"));
  m.alphaMap = rman.getTexture(getTextFromList("TerrainMaterialTab_Materialmap"));
  m.materialTex0 = rman.getTexture(getTextFromList("TerrainMaterialTab_MaterialTex0"));
  m.materialTex1 = rman.getTexture(getTextFromList("TerrainMaterialTab_MaterialTex1"));
  m.materialTex2 = rman.getTexture(getTextFromList("TerrainMaterialTab_MaterialTex2"));
  m.materialTex3 = rman.getTexture(getTextFromList("TerrainMaterialTab_MaterialTex3"));
  
  m.terrainSize = parseInt( getTextFromInput("TerrainMaterialTab_TerrainSize") );
  m.materialSize = parseFloat( getTextFromInput("TerrainMaterialTab_MaterialSize") );
  m.materialBlendFactor[0] = parseFloat( getTextFromInput("TerrainMaterialTab_MaterialBlendFactor0") );
  m.materialBlendFactor[1] = parseFloat( getTextFromInput("TerrainMaterialTab_MaterialBlendFactor1") );
  m.materialBlendFactor[2] = parseFloat( getTextFromInput("TerrainMaterialTab_MaterialBlendFactor2") );
  m.materialBlendFactor[3] = parseFloat( getTextFromInput("TerrainMaterialTab_MaterialBlendFactor3") );
  m.materialBlendRadius = parseFloat( getTextFromInput("TerrainMaterialTab_MaterialBlendRadius") );
  m.updateStep = parseFloat( getTextFromInput("TerrainMaterialTab_UpdateStep") );
  
  m.ambient.x = parseFloat( getTextFromInput("TerrainMaterialTab_Ambient0") );
  m.ambient.y = parseFloat( getTextFromInput("TerrainMaterialTab_Ambient1") );
  m.ambient.z = parseFloat( getTextFromInput("TerrainMaterialTab_Ambient2") );
  
  m.diffuse.x = parseFloat( getTextFromInput("TerrainMaterialTab_Diffuse0") );
  m.diffuse.y = parseFloat( getTextFromInput("TerrainMaterialTab_Diffuse1") );
  m.diffuse.z = parseFloat( getTextFromInput("TerrainMaterialTab_Diffuse2") );
}
function materialTabChangeEffect()
{
  updateMaterialList("Scene_Material_EffectList","Scene_Material_MaterialList");
}

function openAddMaterialDiaglog()
{
  $('#addMaterialDialog').dialog('open')
}
function addMaterial()
{
  var eName = getTextFromList("Scene_Material_EffectList");
  var eIdx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.effects[eIdx];
  
  var className =  getTextFromList("addMaterialDialog_TypeList");
  
  var materialClassName = "gew"+ className;
  var mName = getTextFromInput("addMaterialDialog_Name");
  
  var isExist = getMaterialFromName(mName)
  if(isExist)
  {
    alert("This material name is already used! Plz choice another");
    return;
  } 
  eval("var m = new "+materialClassName+"(e,mName)");
  $("#addMaterialDialog").dialog("close");
  updateMaterialList("Scene_Material_EffectList","Scene_Material_MaterialList");
}
function updateMaterialList(uiEffectListId,uiMaterialListId)
{
  var eName = getTextFromList(uiEffectListId);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var eIdx = getEffectIdx(eName);
  if(eIdx==-1)
    return;
  var mList = screen.scene3d.effects[eIdx].materialList;
  var len = mList.length;
  var uiMaterialList = document.getElementById(uiMaterialListId);
  uiMaterialList.options.length =0;
  for(var i in mList)
  {
    var op=document.createElement('option');
    op.text = i;
    uiMaterialList.add(op,null);
  }
}
///////////////////////////////////////////////////////////////////
// Effect functions
function removeEffect()
{
  var eName = getTextFromList("Scene_Effect_orderList");
  var idx = getEffectIdx(eName);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var e = screen.scene3d.getEffect(eName);
  if (confirm("Are you sure want to delete " + eName + "?")) {
    e.destructor();
    updateEffectList();
  }
}
function addSkyboxEffect()
{
  var texName = getTextFromList("addSkyboxEffectDialog_TextureList");
  var texture = this.game.resourceManager.getTexture(texName);
  var size = parseInt(getTextFromInput("addSkyboxEffectDialog_Size"),10);
  var e = new gewSkyboxEffect(game,texture,size);
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  screen.scene3d.addEffect(e);
  updateEffectList();  
  $("#addSkyboxEffectDialog").dialog("close");
}
function addEffect()
{
  var eName = getTextFromList("Scene_Effect_AddList");
  var isHave = getEffectIdx(eName);
  if(isHave!=-1)
    return;
    
  
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  
  if (eName == "CSMEffect") {
    var e = new gewCSMEffect(screen.scene3d);
    screen.scene3d.addEffect(e);
    updateEffectList();
    return;
  }
  if (eName == "SkyboxEffect") {
    $("#addSkyboxEffectDialog").dialog("open");
    return;
  }
  
  eval("var e = new gew"+eName+"(this.game)")
  screen.scene3d.addEffect(e);
  updateEffectList();  
}
function getEffectIdx(name)
{
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var eList = screen.scene3d.effects;
  var len = eList.length;
  for(var i =0;i<len;i++)
  {
    if(name== eList[i].name)
      return i;
  }
  return -1;
}
function changeRenderOrder(isUp)
{
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var eList = screen.scene3d.effects;
  var len = eList.length;
  var uiList = document.getElementById("Scene_Effect_orderList");
  var op = uiList.options[uiList.selectedIndex];
  if(!op)
    return;
  var selectedName = op.text;
  var idx = getEffectIdx(selectedName);
  if(idx==-1)
    return;
  if(isUp&&idx>0)
  {
    var temp = eList[idx];
    eList[idx] = eList[idx-1];
    eList[idx-1] = temp;     
  }
  if(!isUp&&idx<(len-1))
  {
    var temp = eList[idx];
    eList[idx] = eList[idx+1];
    eList[idx+1] = temp;     
  }  
  updateEffectList();
}

// List of all UI_Select_Effect_Element need to be update
var UI_Select_Effect_Element_Ids = [
  "Scene_Effect_orderList",
  "Scene_Material_EffectList",
];
function updateEffectList()
{
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var eList = screen.scene3d.effects;
  var len = eList.length;
    
  var elementNum = UI_Select_Effect_Element_Ids.length;  
  for (var ele = 0; ele < elementNum; ele++) {
    var uiList = document.getElementById(UI_Select_Effect_Element_Ids[ele]);
    uiList.options.length = 0;
    for (var i = 0; i < len; i++) {
      var op = document.createElement('option');
      op.text = eList[i].name;
      uiList.add(op, null);
    }
  }
}
function updateEffectListInto(listId,name)
{
  var screen = this.game.getScreen(DESIGN_SCREEN_ID);
  var eList = screen.scene3d.effects;
  var len = eList.length;
  
  var uiList = document.getElementById(listId);
  uiList.options.length = 0;
  for (var i = 0; i < len; i++) {
    var op = document.createElement('option');
    op.text = eList[i].name;
    uiList.add(op, null);
    if(name==eList[i].name)
      uiList.selectedIndex = i;
  }
}
function DesignScreen(game)
{
  gewScreen.call(this, game);
  this.scene3d = new gewScene3D(this.game,                    
                                1024,1024,
                                1024,64,
                                true);
  shadowMap = this.scene3d.shadowMap;
  this.drawToolPoint = null;
  this.drawToolNormal = new gewVec3();
  
  this.onTick = function(mls)
  {
    var gl = this.game.gl;
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    this.scene3d.render();
    var drawer = this.scene3d.debugDrawer;
    gl.enableVertexAttribArray(drawer.inPosition);
    if (this.selectedNode) {
      gl.enable(gl.DEPTH_TEST);
      gl.uniform4f(drawer.inColor,0.9,1.,1.,1.);
      this.selectedNode.debugDraw();
      gl.disable(gl.DEPTH_TEST);
    }
    if (currentTool) {
      var tree = $("#Node_tab_NodeTree").dynatree("getTree");
      var ui_node = tree.getActiveNode();
      if (ui_node&& ui_node.sceneNode.modelMat ) {
        var sceneNode = ui_node.sceneNode;
        if (!sceneNode || !sceneNode.localSphere) 
          var r = 5;
        else 
          var r = sceneNode.worldSphere.radius;
        
        var nodeCenter = new gewVec3(sceneNode.modelMat.data[12], sceneNode.modelMat.data[13], sceneNode.modelMat.data[14]);
        switch (currentTool) {
          case NODE_TOOL_MOVE:
            drawMoveTool(gl, drawer, this.scene3d, nodeCenter, r);
            break;
          case NODE_TOOL_SCALE:
            drawScaleTool(gl, drawer, this.scene3d, nodeCenter, r);
            break;
          case NODE_TOOL_ROTATE:
            drawRotateTool(gl, drawer, this.scene3d, nodeCenter, r,this.rotateToolStartPoint,this.rotateToolEndPoint);
            break;
          case GRASS_POINT_PAINT:
            drawPaintTool(gl, drawer, this.scene3d, this.drawToolPoint, this.drawToolNormal);
            break;
          case GRASS_BOX_PAINT:
            drawPaintBoxTool(gl, drawer, this.scene3d, this.drawToolPoint, this.drawToolNormal, parseFloat(getTextFromInput("GrassNodeTab_BoxPaintRadius")));
            break;
          case NODE_POINT_PAINT:
            drawPaintTool(gl, drawer, this.scene3d, this.drawToolPoint, this.drawToolNormal);
            break;
        }
      }
      //drawTool(NODE_TOOL_MOVE,gl,drawer,this.scene3d,new gewVec3(5,0,0))
      //drawRotateTool(gl,drawer,this.scene3d,new gewMat4());
    }
    elapseMls += mls;
    frameCount++;
    if (elapseMls >= 2000) 
    {
      var fps = (frameCount / (elapseMls/1000)).toFixed(2);
      renderFPS.value =  fps;
      elapseMls = 0;
      frameCount = 0;
    }
    this.scene3d.postProcessing();
  }
  this.init = function()
  {
    var game = this.game;
    var gl = this.game.gl;
    var scene3d = this.scene3d;
    var root = scene3d.root;
    var camera_system = scene3d.camera_system;
    // init camera
    var cam = camera_system.createCamera(gewWorldCamera,root);
    this.camera = cam;
    this.camX = -30.;
    this.camY = 30.;
    this.camZ = 30.1;
    cam.setPositionXYZ(9.0,this.camY,this.camZ);
    cam.m_look_at_position = new gewVec3(-30.0,0.0,30.0);
    cam.setDesiredPos(new gewVec3(this.camX, this.camY, this.camZ));
    cam.setAspectRatio(game.width / game.height);    
    cam.setPitch(-GEW_MATH_PI / 4);
    cam.setFov(60.0);
    cam.setNear(1.0);
    cam.setFar(1000);
    cam.setViewport(0, 0,game.width, game.height);
    camera_system.setActiveCamera(cam);
    this.camera = cam;
    var rmanager = game.resourceManager;
    
    /*
    //// SKYBOX
    var skyTexParam = new gewTextureParameter(gl.NEAREST,gl.NEAREST,gl.MIRRORED_REPEAT,gl.MIRRORED_REPEAT);
    rmanager.load("sky", "Resource/skybox/sun45.jpg",true,true,skyTexParam); 
    var skyE = new gewSkyboxEffect(game,rmanager.getTexture("sky"),512);
    scene3d.addEffect(skyE);
    
    
    //var shadowE = new gewCSMEffect(this.scene3d);
    //scene3d.addEffect(shadowE);
    //var shadowM = new gewCSMMaterial(shadowE,"shaodowM");
    
    var effect = new gewTerrainEffect(game);
    scene3d.addEffect(effect);
  
    var phongE = new gewPhongEffect(game);
    scene3d.addEffect(phongE);
    
    var material = new gewTerrainMaterial(effect);
    
    var woodM = new gewPhongMaterial(phongE,"wood");
    var texParam = new gewTextureParameter(gl.NEAREST,gl.NEAREST,gl.MIRRORED_REPEAT,gl.MIRRORED_REPEAT);
    var texParam2 = new gewTextureParameter(gl.LINEAR,gl.LINEAR_MIPMAP_LINEAR,gl.MIRRORED_REPEAT,gl.MIRRORED_REPEAT);
    var texParam3 = new gewTextureParameter(gl.LINEAR,gl.LINEAR_MIPMAP_LINEAR,gl.MIRRORED_REPEAT,gl.MIRRORED_REPEAT);
    var texParam4 = new gewTextureParameter(gl.LINEAR,gl.LINEAR,gl.CLAMP_TO_EDGE,gl.CLAMP_TO_EDGE)
    rmanager.load("texturemap","Resource/terrain/texture_map.jpg",true,true,texParam2,true);
    rmanager.load("alphamap","Resource/terrain/material_map2.png",true,true,texParam3,true);
    rmanager.load("materialmap","Resource/terrain/materials.jpg",true,true,texParam4,true);
    rmanager.load("heightmap","Resource/terrain/height_map3.fm",true,true);
    
    rmanager.load("k1","Resource/knight.ism1",true,true);
    rmanager.load("k2","Resource/knight.obj",true,true);
    
    woodM.texture = rmanager.getTexture("alphamap");
    material.heightMap = rmanager.getFloatMap("heightmap");
    //shadowM.heightMap = rmanager.getFloatMap("heightmap");
    
    material.textureMap = rmanager.getTexture("texturemap");
    material.alphaMap = rmanager.getTexture("alphamap");
    material.materialAtlas = rmanager.getTexture("materialmap");    
    
    var terrain_node = new gewTerrainNode(gl,64,1,6,"terrain_node");
    terrain_node.addMaterial(material);
    terrain_node.debugName = "terrain";
    root.appendChild(terrain_node);
    this.terrain = terrain_node;
    scene3d.terrain = terrain_node;
    
    ///// WATER
    var waterE = new gewWaterEffect(game);
    scene3d.addEffect(waterE);
    
    var waterM = new gewWaterMaterial(waterE);
    var waterTexParam = new gewTextureParameter(gl.LINEAR,gl.LINEAR_MIPMAP_LINEAR,gl.REPEAT,gl.REPEAT);    
    
    rmanager.load("waterbump", "Resource/water/waterbump.jpg",true,true,waterTexParam);
    rmanager.load("water_mesh","Resource/water/water_surface.obj",true,true);
     
    waterM.normalMap = rmanager.getTexture("waterbump");
    waterM.reflectionMap = rmanager.getTexture("sky");
    var water_node = new gewWaterNode();
    root.appendChild(water_node);
    water_node.setMesh(rmanager.getMesh("water_mesh"));
    water_node.addMaterial(waterM);
    water_node.setPositionXYZ(0,2.0,0);
    water_node.name = "water";
    
    ///// GRASS
    var gparam = new gewTextureParameter(gl.LINEAR,gl.LINEAR_MIPMAP_LINEAR,gl.CLAMP_TO_EDGE ,gl.CLAMP_TO_EDGE );
    rmanager.load("grasspack","Resource/grassPack.png",true,true,gparam,true,true);
    //rmanager.load("perlin_noise","Resource/perlin_noise.jpg",true,true,gparam,true,true);
    
    var grassE = new gewGrassEffect(game);
    scene3d.addEffect(grassE);
    var grassM = new gewGrassMaterial(grassE);
    grassM.grassPackTexture = rmanager.getTexture("grasspack");
    //grassM.noiseTexture = rmanager.getTexture("perlin_noise");
    */    
    renderFPS = document.getElementById("fps");    
  }
  this.isDrag = false;
  this.onMouseDown = function(e)
  {
    this.camera.onMouseDown(e);
    this.pickedPoint = new gewVec2(e.canvasX,e.canvasY);
    if(e.altKey||e.ctrlKey||e.shiftKey)
      return;   
    var tree = $("#Node_tab_NodeTree").dynatree("getTree");
    var ui_node = tree.getActiveNode();
    if(ui_node)
      var sceneNode = ui_node.sceneNode;
    if(currentTool==NODE_POINT_PAINT)
    {
      paintNode(sceneNode,this.drawToolPoint,this.drawToolNormal);
    }
    if(currentTool==GRASS_POINT_PAINT)
    {
      var className = getClassName(sceneNode);
      if(className=="gewGrassNode")
      {
        var paintPoint = this.drawToolPoint;
        sceneNode.addGrassClump(paintPoint.x,paintPoint.y,paintPoint.z);
        sceneNode.pointBrushs.push(paintPoint.dup());
        sceneNode.updateGLBuffers();
        document.getElementById("GrassNodeTab_ClumpCount").value = sceneNode.clumpNum;
      }      
    }
    if(currentTool==GRASS_BOX_PAINT)
    {
      var className = getClassName(sceneNode);
      if(className=="gewGrassNode")
      {
        var paintPoint = this.drawToolPoint;
        var terrianE = this.scene3d.effects[getEffectIdx("TerrainEffect")];
        for(var m in terrianE.materialList)
        {
          var heightmap = terrianE.materialList[m].heightMap;
        }
        paintGrassByBox(sceneNode,paintPoint.x,paintPoint.z,
                        parseFloat(getTextFromInput("GrassNodeTab_BoxPaintRadius")),
                        parseFloat(getTextFromInput("GrassNodeTab_BoxPaintDensity")),
                        heightmap);
        document.getElementById("GrassNodeTab_ClumpCount").value = sceneNode.clumpNum;
      }
    }
    if(currentTool==NODE_TOOL_SELECT)
    {
      var scene3d = this.scene3d;
      var ray = getPickingRay(e.canvasX,e.canvasY,this.camera,scene3d.inverseViewMat);
      var node = ray.colisionWithTreeNode(scene3d,100);
      this.selectedNode = node;            
      var tree = $("#Node_tab_NodeTree").dynatree("getTree");
      tree.activateKey(node.name);   
    }
    
    if(currentTool==NODE_TOOL_MOVE||
       currentTool==NODE_TOOL_SCALE||
       currentTool==NODE_TOOL_ROTATE)
    {
      currentPickColor = null;
      this.startNodePosition = sceneNode.getPosition();
      this.startNodeScale = sceneNode.getScale();
      this.startNodeRotateAxis = sceneNode.getRotateAxis();
      this.startNodeRotateAngle = sceneNode.getRotateAngle();
      this.gl.flush(); 
      var x = e.canvasX;
      var y = this.game.height-e.canvasY;
      
      var size = 10;
      var lx = x-size/2;
      var ly = y-size/2;
      
      if(lx<0)
        lx =0;
      if(ly<0)
        ly =0;
      var wsize = hsize = size;
      
      if(lx+size > this.game.width)
        wsize = this.game.width-lx;
      if(ly+size > this.game.height)
        hsize = this.game.height-ly;  
      var colors = this.gl.readPixels(lx,ly,wsize,hsize, gl.RGBA, gl.UNSIGNED_BYTE);
      var pixelNum = colors.length/4;
      for(var p=0;p<pixelNum;p++)
      {
        if (colors[p * 4] == 255 && colors[p * 4 + 1] == 0 && colors[p * 4 + 2] == 0) {
          currentPickColor = PICK_COLOR_RED;break;
        }
        else if (colors[p * 4] == 0 && colors[p * 4 + 1] == 255 && colors[p * 4 + 2] == 0) {
          currentPickColor = PICK_COLOR_GREEN;break;
        }
        else if (colors[p * 4] == 0 && colors[p * 4 + 1] == 0 && colors[p * 4 + 2] == 255) {
          currentPickColor = PICK_COLOR_BLUE;break;
        }
        else if (colors[p * 4] == 255 && colors[p * 4 + 1] == 255 && colors[p * 4 + 2] == 255) {
          currentPickColor = PICK_COLOR_WHITE;break;
        }
      }
      if(!currentPickColor)
        currentTool=NODE_TOOL_SELECT;
    }
  }
  this.onMouseMove = function(e)
  {
    this.camera.onMouseMove(e);
    if(e.altKey||e.ctrlKey||e.shiftKey)
      return;
    if (currentTool) {
      var tree = $("#Node_tab_NodeTree").dynatree("getTree");
      var ui_node = tree.getActiveNode();
      if(ui_node)
        var sceneNode = ui_node.sceneNode;
    }
    
    if(currentTool==NODE_TOOL_ROTATE)
    {
      if (currentPickColor) {
        var p1 = sceneNode.worldSphere.center.dup();
        var p2 = sceneNode.worldSphere.center.dup();
        var p3 = sceneNode.worldSphere.center.dup();
        switch (currentPickColor) {
          case PICK_COLOR_RED:
            var axis = new gewVec3(1,0,0);
            var ox = new gewVec3(0,1,0); 
            p2.y += 5;
            p3.z += 5;
            break;
          case PICK_COLOR_GREEN:
            var axis = new gewVec3(0,1,0);
            var ox = new gewVec3(1,0,0);
            p2.x += 5;
            p3.z += 5;
            break;
          case PICK_COLOR_BLUE:
            var axis = new gewVec3(0,0,1);
            var ox = new gewVec3(1,0,0);
            p2.x += 5;
            p3.y += 5;
            break;
        }
        var plane = new gewPlane(p1, p2, p3);
        var ray = getPickingRay(e.canvasX, e.canvasY, this.camera, this.scene3d.inverseViewMat);
        var coliPoint = ray.colisionWithPlane(plane);
        var mp2 = coliPoint.sub(p1);
        mp2.normalize();
        this.rotateToolEndPoint = mp2;
        
        if (this.rotateToolStartPoint) 
          var mp1 = this.rotateToolStartPoint;
        else {
          var start_ray = getPickingRay(this.pickedPoint.x, this.pickedPoint.y, this.camera, this.scene3d.inverseViewMat);
          var start_coliPoint = start_ray.colisionWithPlane(plane);
          var mp1 = start_coliPoint.sub(p1);
          mp1.normalize();
          this.rotateToolStartPoint = mp1;
        }        
        var a1 = mp1.angleFrom(ox);
        var a2 = mp2.angleFrom(ox);         
        
        switch (currentPickColor) {
          case PICK_COLOR_RED:
            if( mp2.z < 0 )
              a2 = -a2;
            if( mp1.z < 0)
              a1 = -a1;
            break;
          case PICK_COLOR_GREEN:
            if( mp2.z > 0 )
              a2 = -a2;
            if( mp1.z > 0)
              a1 = -a1;
            break;
          case PICK_COLOR_BLUE:
            if( mp2.y < 0 )
              a2 = -a2;
            if( mp1.y < 0)
              a1 = -a1;
            break;
        }
        var angle = a2-a1;      
        var mat = gewMat4.getRotate(axis,angle);        
        var currentMat = gewMat4.getRotate( this.startNodeRotateAxis, this.startNodeRotateAngle* GEW_MATH_DEGREE_TO_RADIAN);
        
        var combineMat = mat.mul(currentMat);
        var new_axis = new gewVec3();
        var new_angle = combineMat.extractRotateAxis(new_axis);
        
        sceneNode.setRotate(new_axis, new_angle*GEW_MATH_RADIAN_TO_DEGREE );
        displayActiveNode(ui_node,1);
      }
    }
    if(currentTool==NODE_TOOL_MOVE||currentTool==NODE_TOOL_SCALE)
    {      
      if(currentPickColor)
      {        
        if(currentTool==NODE_TOOL_MOVE)
          document.body.style.cursor='move';
        else
          document.body.style.cursor='all-scroll';
        
        var p1 =  sceneNode.worldSphere.center.dup();
        var p2 =  sceneNode.worldSphere.center.dup();
        var p3 =  sceneNode.worldSphere.center.dup();
        switch(currentPickColor)
        {
          case PICK_COLOR_RED:
          case PICK_COLOR_WHITE:
            p2.x+=5;
            p3.y+=5;
            break;
          case PICK_COLOR_GREEN:
            p2.x+=5;
            p3.y+=5;
            break;
          case PICK_COLOR_BLUE:
            p2.x+=5;
            p3.z+=5;
            break;
        }
        var plane = new gewPlane(p1,p2,p3);
        var ray = getPickingRay(e.canvasX,e.canvasY,this.camera,this.scene3d.inverseViewMat);
        var start_ray = getPickingRay(this.pickedPoint.x,this.pickedPoint.y,this.camera,this.scene3d.inverseViewMat);
        var coliPoint = ray.colisionWithPlane(plane);
        var start_coliPoint = start_ray.colisionWithPlane(plane);
        
        var delta = coliPoint.sub(start_coliPoint);
        switch(currentPickColor)
        {
          case PICK_COLOR_RED:
            delta.y=0;
            delta.z=0;
            break;
          case PICK_COLOR_GREEN:
            delta.x=0;
            delta.z=0;
            break;
          case PICK_COLOR_BLUE:
            delta.x=0;
            delta.y=0;
            break;
        }
        if (currentTool == NODE_TOOL_MOVE) 
          sceneNode.setPosition(this.startNodePosition.add(delta));
        else if (currentTool == NODE_TOOL_SCALE) 
        {
          var r = sceneNode.worldSphere.radius*2;
          switch(currentPickColor)
          {
            case PICK_COLOR_RED:
              sceneNode.setScaleXYZ( this.startNodeScale.x*(1+delta.x/r),this.startNodeScale.y,this.startNodeScale.z);
              break;
            case PICK_COLOR_GREEN:
              sceneNode.setScaleXYZ( this.startNodeScale.x,this.startNodeScale.y*(1+delta.y/r),this.startNodeScale.z);
              break;
            case PICK_COLOR_BLUE:
              sceneNode.setScaleXYZ( this.startNodeScale.x,this.startNodeScale.y,this.startNodeScale.z*(1+delta.z/r));
              break;
            case PICK_COLOR_WHITE:
              sceneNode.setScaleXYZ( this.startNodeScale.x*(1+delta.x/r),this.startNodeScale.y*(1+delta.x/r),this.startNodeScale.z*(1+delta.x/r));
              break;
          }
        }
        displayActiveNode(ui_node,1);
      }
    }
    
    if(currentTool==GRASS_BOX_PAINT||
       currentTool==GRASS_POINT_PAINT||
       currentTool==NODE_POINT_PAINT)
    {
      var ray = getPickingRay(e.canvasX,e.canvasY,this.camera,this.scene3d.inverseViewMat);
      
      var terrianE = this.scene3d.effects[getEffectIdx("TerrainEffect")];
      for(var m in terrianE.materialList)
      {
        var heightmap = terrianE.materialList[m].heightMap;
      }
      this.drawToolPoint=ray.colisionWithHeightMap(heightmap ,40,5,0.05,this.drawToolNormal);
      
    }          
  }
  this.onMouseOut = function(e)
  {
    currentPickColor=null;
    document.body.style.cursor='default' 
  }
  this.onMouseUp = function(e)
  {
    this.camera.onMouseUp(e);
    if(e.altKey||e.ctrlKey||e.shiftKey)
      return;
    document.body.style.cursor='default'
    currentPickColor = null;
    this.rotateToolStartPoint = null;
    this.rotateToolEndPoint = null;
  }
  this.onMouseWheel = function(e)
  {
    this.camera.onMouseWheel(e);
  }
  this.onKeyDown = function(e)
  {    
    this.camera.onKeyDown(e);
  }
  this.onKeyPress = function(e)
  {
    if( e.keychar =='f')
    {
      this.scene3d.isUseFilter = ! this.scene3d.isUseFilter;
    }
    
    var tree = $("#Node_tab_NodeTree").dynatree("getTree");
    var ui_node = tree.getActiveNode();
    if(ui_node&&ui_node.sceneNode )
    {
      switch( e.keychar)
      {
        case 't':
          currentTool = NODE_TOOL_MOVE;
          break;
        case 'r':
          currentTool = NODE_TOOL_ROTATE;
          break;
        case 'e':
          currentTool = NODE_TOOL_SCALE;
          break;
        case 'p':
          currentTool = NODE_POINT_PAINT;
          break;   
        case 'y':
          currentTool = NODE_TOOL_SELECT;
          break;       
      }
    }
        
    this.camera.onKeyPress(e);
  }
  this.onKeyUp = function(e)
  {
    this.camera.onKeyUp(e);
  }
}

function drawMoveTool(gl,drawer,scene3d,center,size)
{
  gl.disable(gl.DEPTH_TEST);
  gl.uniform4f(drawer.inColor,0.,0.,0.,1.);
  drawCoordinateLine(gl,drawer,scene3d,center,size );
  
  var r = size/10;
  var h = size/3;
  
  //var viewMat = scene3d.viewMat.dup();
  //var projMat = makeOrtho(-30,30,-30,30,1,1000);
  //var viewProj = projMat.mul(viewMat);
  var viewProj = scene3d.viewProjectMat.dup();
  var modelMat = gewMat4.getTranslateXYZ(center.x,center.y+size,center.z);
  var mvpMat = viewProj.mul(modelMat);
  
  var red = new gewVec3(1,0,0);
  var green = new gewVec3(0,1,0);
  var blue = new gewVec3(0,0,1);
  
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawCone(gl,drawer,r,30,h,green);  
  
  modelMat = gewMat4.getTranslateXYZ(center.x+size,center.y,center.z);
  var rotateMat = gewMat4.getRotateXYZ(0,0,1,-90*GEW_MATH_DEGREE_TO_RADIAN);
  modelMat.mul(rotateMat,modelMat)
  viewProj.mul(modelMat,mvpMat);
  
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawCone(gl,drawer,r,30,h,red);  
  
  modelMat = gewMat4.getTranslateXYZ(center.x,center.y,center.z+size);
  rotateMat = gewMat4.getRotateXYZ(1,0,0,90*GEW_MATH_DEGREE_TO_RADIAN);
  modelMat.mul(rotateMat,modelMat)
  viewProj.mul(modelMat,mvpMat);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawCone(gl,drawer,r,30,h,blue);    
}
function drawScaleTool(gl,drawer,scene3d,center,size)
{
  gl.disable(gl.DEPTH_TEST);
  gl.uniform4f(drawer.inColor,0.,0.,0.,1.);
  drawCoordinateLine(gl,drawer,scene3d,center,size );
  
  var boxSize = size/10;
  var aabb = new gewAabb(new gewVec3(-boxSize,-boxSize,-boxSize), 
                         new gewVec3(boxSize,boxSize,boxSize));
  
  //var viewMat = scene3d.viewMat.dup();
  //var projMat = makeOrtho(-30,30,-30,30,1,1000);
  //var viewProj = projMat.mul(viewMat);
  var viewProj = scene3d.viewProjectMat.dup();
  var modelMat = gewMat4.getTranslateXYZ(center.x,center.y+size,center.z);
  var mvpMat = viewProj.mul(modelMat);
  
  var red = new gewVec3(1,0,0);
  var green = new gewVec3(0,1,0);
  var blue = new gewVec3(0,0,1);
  var white = new gewVec3(1,1,1);
  
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawAabb(gl, drawer, aabb,green,true);
  
  modelMat = gewMat4.getTranslateXYZ(center.x+size,center.y,center.z);
  var rotateMat = gewMat4.getRotateXYZ(0,0,1,-90*GEW_MATH_DEGREE_TO_RADIAN);
  modelMat.mul(rotateMat,modelMat)
  viewProj.mul(modelMat,mvpMat);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawAabb(gl, drawer, aabb,red,true);
  
  modelMat = gewMat4.getTranslateXYZ(center.x,center.y,center.z+size);
  rotateMat = gewMat4.getRotateXYZ(1,0,0,90*GEW_MATH_DEGREE_TO_RADIAN);
  modelMat.mul(rotateMat,modelMat)
  viewProj.mul(modelMat,mvpMat);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawAabb(gl, drawer, aabb,blue,true);
  
  modelMat = gewMat4.getTranslateXYZ(center.x,center.y,center.z);
  viewProj.mul(modelMat,mvpMat);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  drawAabb(gl, drawer, aabb,white,true);      
}
function drawCoordinateLine(gl,drawer,scene3d,center,length)
{
  var ver = new WebGLFloatArray([center.x,center.y,center.z,
                                 center.x+length,center.y,center.z,
                                 center.x,center.y+length,center.z,
                                 center.x,center.y,center.z+length]);
  var ind = new WebGLUnsignedShortArray([0,1,0,2,0,3]);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, scene3d.viewProjectMat.data);
  drawPrimitives(gl,drawer,ver,6,ind,gl.LINES);
}

function drawRotateTool(gl,drawer,scene3d,center,radius,startPoint,endPoint)
{
  //var viewMat = scene3d.viewMat.dup();
  //var projMat = makeOrtho(-30,30,-30,30,1,1000);
  //var viewProj = projMat.mul(viewMat);
  var modelMat = gewMat4.getTranslateXYZ(center.x,center.y,center.z);
  var viewProj = scene3d.viewProjectMat.dup();
  var mvpMat = viewProj.mul(modelMat);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, mvpMat.data);
  if( startPoint)
  {
    console.log(startPoint);
    var spV = new WebGLFloatArray([0,0,0,startPoint.x*radius,startPoint.y*radius,startPoint.z*radius]);
    var spI = new WebGLUnsignedShortArray([0,1]);
    gl.uniform4f(drawer.inColor,0.5,0.5,0.5,1.);
    drawPrimitives(gl,drawer,spV,2,spI,gl.LINES);  
  }
  if( endPoint)
  {
    var epV = new WebGLFloatArray([0,0,0,endPoint.x*radius,endPoint.y*radius,endPoint.z*radius]);
    var epI = new WebGLUnsignedShortArray([0,1]);
    gl.uniform4f(drawer.inColor,0.5,0.5,0.5,1.);
    drawPrimitives(gl,drawer,epV,2,epI,gl.LINES);
  }
  var stacks = 30;
  var sint1 = [],cost1 = [];
  circleTable(sint1,cost1, stacks);
  
  var ver = [];
  var ind = [];  
  for (i=0; i<stacks; i++)
  {
    ver.push(sint1[i]*radius,0,cost1[i]*radius);
    if(i==0)
      ind.push(0);
    else  
      ind.push(i,i);
  }
  ind.push(0);
  var verbuf = new WebGLFloatArray(ver);
  var indbuf = new WebGLUnsignedShortArray(ind);
  gl.uniform4f(drawer.inColor,0.,1.,0.,1.);
  drawPrimitives(gl,drawer,verbuf,ind.length,indbuf,gl.LINES);    
  delete verbuf;
  delete indbuf;
  
  ver = [];
  ind = [];  
  for (i=0; i<stacks; i++)
  {
    ver.push(0,sint1[i]*radius,cost1[i]*radius);
    if(i==0)
      ind.push(0);
    else  
      ind.push(i,i);
  }
  ind.push(0);
  var verbuf = new WebGLFloatArray(ver);
  var indbuf = new WebGLUnsignedShortArray(ind);
  gl.uniform4f(drawer.inColor,1.,0.,0.,1.);
  drawPrimitives(gl,drawer,verbuf,ind.length,indbuf,gl.LINES);
  delete verbuf;
  delete indbuf;
  
  ver = [];
  ind = [];
  for (i=0; i<stacks; i++)
  {
    ver.push(sint1[i]*radius,cost1[i]*radius,0);
    if(i==0)
      ind.push(0);
    else  
      ind.push(i,i);
  }
  ind.push(0);
  var verbuf = new WebGLFloatArray(ver);
  var indbuf = new WebGLUnsignedShortArray(ind);
  gl.uniform4f(drawer.inColor,0.,0.,1.,1.);
  drawPrimitives(gl,drawer,verbuf,ind.length,indbuf,gl.LINES);
  delete verbuf;
  delete indbuf;
  
}
function drawPaintBoxTool(gl,drawer,scene3d,point,normal,hsize)
{
  if(!point)
    return;
  gl.enable(gl.DEPTH_TEST);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, scene3d.viewProjectMat.data);
  
  gl.uniform4f(drawer.inColor,1.,0.,0.,1.);
  var hsizeVec = new gewVec3(hsize,hsize,hsize);
  var min = point.sub(hsizeVec);
  var max = point.add(hsizeVec);
  var aabb = new gewAabb(min ,max);
  drawAabb(gl, drawer,aabb);
  drawVerticesAsPoint(gl, drawer, new WebGLFloatArray([point.x,point.y,point.z]), 1);
  
  gl.uniform4f(drawer.inColor,0.,1.,0.,1.);
  var ver = new WebGLFloatArray([point.x,point.y,point.z,
                                 point.x+normal.x*12,point.y+normal.y*12,point.z+normal.z*12]);
  var ind = new WebGLUnsignedShortArray([0,1]);  
  drawPrimitives(gl,drawer,ver,2,ind,gl.LINES);
}

function drawPaintTool(gl,drawer,scene3d,point,normal)
{
  if(!point)
    return;
  gl.enable(gl.DEPTH_TEST);
  gl.uniformMatrix4fv(drawer.modelViewProjectionMat, false, scene3d.viewProjectMat.data);
  
  gl.uniform4f(drawer.inColor,1.,0.,0.,1.);
  drawVerticesAsPoint(gl, drawer, new WebGLFloatArray([point.x,point.y,point.z]), 1);
  
  gl.uniform4f(drawer.inColor,0.,1.,0.,1.);
  var ver = new WebGLFloatArray([point.x,point.y,point.z,
                                 point.x+normal.x*12,point.y+normal.y*12,point.z+normal.z*12]);
  var ind = new WebGLUnsignedShortArray([0,1]);  
  drawPrimitives(gl,drawer,ver,2,ind,gl.LINES);
}

function paintGrassByBox(grassNode,centerX,centerZ,halfSize,density,heightMap)
{
  var grids = [];
  var gridSize = 1/Math.sqrt(density);
  for(var dx=-halfSize;dx<halfSize;dx+=gridSize)
  for(var dz=-halfSize;dz<halfSize;dz+=gridSize)
  {
    var grid = {};
    grid.maxX = (centerX+dx)+gridSize/2;
    grid.minX = (centerX+dx)-gridSize/2;
    grid.maxZ = (centerZ+dz)+gridSize/2;
    grid.minZ = (centerZ+dz)-gridSize/2;
    grid.isHaveClump = false; 
    grids.push(grid);
  } 
  var clumpNum = grassNode.clumpNum;
  var clumpPos = grassNode.clumpPositions;
  
  var gridNum =grids.length;
  for(var i=0;i<clumpNum;i++)
  {
    var pos = clumpPos[i];
    
    for(var j=0;j<gridNum;j++)
    {
      var grid = grids[j];
      if( pos.x<grid.maxX&& pos.x>grid.minX&&
          pos.z<grid.maxZ&& pos.z>grid.minZ )
      {
        grid.isHaveClump = true;
      }
    }
  }
  var isReachLimit = false;
  for (var j = 0; j < gridNum; j++) {
    if(!grids[j].isHaveClump)
    {
      var x = gewMix(grids[j].maxX, grids[j].minX, Math.random());
      var z = gewMix(grids[j].maxZ, grids[j].minZ, Math.random());
      var y = heightMap.interpolationAt(x,z);
      if(grassNode.clumpNum>10800)
      {
        alert("gewGrassNode::addGrassClump: Can't not add more clump for this Grass node( maximum 10800 reach)");
        isReachLimit = true;
        break;
      }
      grassNode.addGrassClump(x,y,z);
      grassNode.clumpPositions.push(new gewVec3(x,y,z));
    }
  }
  // Update box brush
  if(!isReachLimit) 
  {
    var boxBrushs = grassNode.boxBrushs;
    var brushNum = boxBrushs.length;
    var box = new gewRec2D( centerX-halfSize, centerX+halfSize,
                            centerZ-halfSize,centerZ+halfSize);
    box.density = density;
    var addBrushs = [];
    addBrushs.push(box);
    for(var i=0;i<brushNum;i++)
    {
      var box2 = boxBrushs[i];
      var test = box.isContainRec2D(box2);
      if(test==GEW_OUT)
        continue;
      if(test==GEW_IN)
      {
        // Remove box2
        boxBrushs.splice(i,1);
        i--;
        brushNum--;
      }
      if(test==GEW_INTERNAL)
      {        
        // Remove box2        
        boxBrushs.splice(i,1);
        i--;    
        brushNum--;    
        // Cut box2 into 4 piece
        var box2_1 = new gewRec2D( box2.minx, box2.maxx, box2.miny, box.miny);
        box2_1.density = box2.density;
        addBrushs.push(box2_1);
        
        var box2_2 = new gewRec2D( box2.minx, box.minx, box.miny, box.maxy);
        box2_2.density = box2.density;
        addBrushs.push(box2_2); 
        
        var box2_3 = new gewRec2D( box.maxx, box2.maxx, box.miny, box.maxy);
        box2_3.density = box2.density;
        addBrushs.push(box2_3);
        
        var box2_4 = new gewRec2D( box2.minx, box2.maxx, box.maxy, box2.maxy);
        box2_4.density = box2.density;
        addBrushs.push(box2_4);
      }
      if( test==GEW_INTERSECT)
      {
        // Special case that no need to cut box2 ( only need reduce its size)
        if( box.minx< box2.minx &&
            box.maxx> box2.maxx)
        {
          if( box.maxy>= box2.maxy)
            box2.maxy = box.miny;
          else
            box2.miny = box.maxy;
          continue;
        }
        if( box.miny< box2.miny &&
            box.maxy> box2.maxy)
        {
          if( box.maxx>= box2.maxx)
            box2.maxx = box.minx;
          else
            box2.minx = box.maxx;
          continue;
        }
        // Remove box2
        boxBrushs.splice(i,1);
        i--; 
        brushNum--;
        if(box.minx > box2.minx && 
           box.maxx < box2.maxx)
        {
          // cut box2 into 3 piece
          var box2_1 = new gewRec2D( box2.minx, box.minx, box2.miny, box2.maxy);
          box2_1.density = box2.density;
          addBrushs.push(box2_1);
          
          if (box.maxy >= box2.maxy) 
            var box2_2 = new gewRec2D(box.minx, box.maxx, box2.miny, box.miny);
          else
            var box2_2 = new gewRec2D(box.minx, box.maxx, box.maxy, box2.maxy);
          box2_2.density = box2.density;
          addBrushs.push(box2_2); 
          
          var box2_3 = new gewRec2D( box.maxx, box2.maxx, box2.miny, box2.maxy);
          box2_3.density = box2.density;
          addBrushs.push(box2_3);
        }
        else if( box.maxx >= box2.maxx)
        {
          // cut into 2 piece
          var box2_1 = new gewRec2D( box2.minx, box.minx, box2.miny, box2.maxy);
          box2_1.density = box2.density;
          addBrushs.push(box2_1);
          
          if (box.maxy >= box2.maxy) 
            var box2_2 = new gewRec2D(box.minx, box2.maxx, box2.miny, box.miny);
          else
            var box2_2 = new gewRec2D(box.minx, box2.maxx, box.maxy, box2.maxy);
          box2_2.density = box2.density;
          addBrushs.push(box2_2); 
        }
        else if( box.minx <= box2.minx)
        {
          // cut into 2 piece
          var box2_1 = new gewRec2D( box.maxx, box2.maxx, box2.miny, box2.maxy);
          box2_1.density = box2.density;
          addBrushs.push(box2_1);
          
          if (box.maxy >= box2.maxy) 
            var box2_2 = new gewRec2D(box2.minx, box.maxx, box2.miny, box.miny);
          else
            var box2_2 = new gewRec2D(box2.minx, box.maxx, box.maxy, box2.maxy);
          box2_2.density = box2.density;
          addBrushs.push(box2_2); 
        }
        
      }
    }    
    for(var i=0;i< addBrushs.length;i++)
      boxBrushs.push(addBrushs[i]);    
  }  
  grassNode.updateGLBuffers();
}






